package com.smartboot.plus.features.cluster;

import com.smartboot.plus.holder.BrokerContextHolder;
import com.smartboot.plus.ignite.cache.MqttNodeCache;
import com.smartboot.plus.utils.SecurePasswordUtil;
import tech.smartboot.feat.cloud.annotation.Autowired;
import tech.smartboot.feat.cloud.annotation.Bean;
import tech.smartboot.feat.core.common.logging.Logger;
import tech.smartboot.feat.core.common.logging.LoggerFactory;
import tech.smartboot.mqtt.client.MqttClient;
import tech.smartboot.mqtt.plugin.spec.BrokerContext;

import java.util.Arrays;

@Bean
public class ClusterConnector {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClusterConnector.class);

    @Autowired
    private BrokerContext brokerContext;

    public void connect(MqttNodeCache remote) {
        if (BrokerContextHolder.getConnectedNodeMap().containsKey(remote.getNodeId())) {
            return;
        }
        MqttClient client = new MqttClient(remote.getClusterEndpoint(), options -> {
            options
                    .setClientId(MqttClientIdGenerator.generate(MqttClientIdGenerator.GenerationStrategy.HYBRID))
                    .setUserName(remote.getClusterUsername())
                    .setPassword(remote.getClusterPassword().getBytes())
                    .setGroup(brokerContext.Options().getChannelGroup())
                    .setKeepAliveInterval(30)
                    .setAutomaticReconnect(true);
        });

        client.connect(ack -> {
            BrokerContextHolder.getConnectedNodeMap().put(remote.getNodeId(), client);
            LOGGER.info("Connected to cluster node {}", remote.getNodeId());
        });
    }


    public void disconnect(String nodeId) {
        MqttClient client = BrokerContextHolder.getConnectedNodeMap().remove(nodeId);
        if (client != null) {
            client.disconnect();
            LOGGER.info("Disconnected from cluster node {}", nodeId);
        }
    }

    public byte[] generate(MqttNodeCache from, MqttNodeCache to) {
        String seed = from.getNodeId() + ":" + to.getNodeId();
        String encrypted = SecurePasswordUtil.hashPassword(from.getNodeId(), seed, "SHA-256", "prefix");

        return encrypted.getBytes();
    }


}
